#include "lrc.h"
#include "tools.h"
char *read_src_file(char *file_name)
{
    FILE *fp = fopen(file_name, "rb");
    if (NULL == fp)
    {
        perror("fopen");
        return NULL;
    }
    fseek(fp, 0, 2);               // 光标移动到最后
    unsigned long len = ftell(fp); // 获取从头到尾长度
    rewind(fp);                    // 光标重置回到开始
    char *file_data = (char *)malloc(len + 1);
    fread(file_data, len, 1, fp);
    fclose(fp);
    return file_data;
}

int strtok_lrc_buf(char *src, char ***dest)
{
    if (NULL == src)
    {
        printf("src null");
        return 0;
    }
    char *tmp = src, *ch;
    int len = 0;
    // 统计行数
    while ((ch = strchr(tmp, '\n')) != NULL)
    {
        tmp = ch + 1;
        len++;
    }
    // 申请指针数组空间
    *dest = (char **)malloc(sizeof(char *) * len);
    tmp = strtok(src, "\r\n");
    int i = 0;
    // 保存切割好的字符串
    (*dest)[i] = tmp;
    while ((tmp = strtok(NULL, "\r\n")) != NULL)
    {
        i++;
        (*dest)[i] = tmp;
    }
    return len;
}

LRC *lrc_head_resolve(char ***data, int *len)
{
    if (NULL == data)
    {
        printf("data null\n");
        return NULL;
    }
    // 统计前几行需要需要特殊处理
    char **src = *data;
    int head_len = 0;
    char key[32] = "", value[32] = "";
    LRC head_data;
    LRC *head_link = NULL;
    while (1)
    {
        memset(&head_data, 0, sizeof(LRC));
        memset(key, 0, sizeof(key));
        memset(value, 0, sizeof(value));
        sscanf(src[head_len], "[%[^:]:%[^]]", key, value); // 获取数据
        head_len++;
        if (strcmp(key, "ti") == 0) // 歌名
        {
            sprintf(head_data.lrc_buf, "歌名: %s", value);
        }
        else if (strcmp(key, "ar") == 0) // 歌手
        {
            sprintf(head_data.lrc_buf, "歌手: %s", value);
        }
        else if (strcmp(key, "al") == 0) // 专辑
        {
            sprintf(head_data.lrc_buf, "专辑: %s", value);
        }
        else if (strcmp(key, "by") == 0) // 制作
        {
            sprintf(head_data.lrc_buf, "制作: %s", value);
        }
        else if (strcmp(key, "offset") == 0) // 延时
        {
            continue;
        }
        else if (atoi(value)) // 识别到数字
        {
            head_len--;
            break;
        }
        else
        {
            continue;
        }
        printf("%s\n", head_data.lrc_buf);
        head_link = insert_double_link(head_link, head_data);
    }
    *len = head_len;
    return head_link;
}

LRC *insert_double_link(LRC *head, LRC src)
{
    LRC *p = (LRC *)malloc(sizeof(LRC));
    *p = src; // 进行值拷贝
    if (NULL == head)
    {
        head = p;
    }
    else
    {
        LRC *tmp = head;
        // 比较第一个节点时间大小
        if (tmp->time > p->time)
        {
            p->next = tmp;
            head = p;
        }
        else
        {
            while (tmp->next != NULL)
            {
                if (tmp->next->time > p->time) // 找到需要插入的位置
                    break;
                tmp = tmp->next;
            }
            p->next = tmp->next;
            tmp->next = p;
        }
    }
    return head;
}

LRC *lrc_resolve(char ***data, int head_len, int len, LRC *head)
{
    if (NULL == head || NULL == data)
    {
        printf("head or data null\n");
        return NULL;
    }
    char **tmp = (*data) + head_len;
    int i = 0;
    char *p_lrc, *p_time;
    LRC lrc_data;
    for (i = 0; i < len - head_len; i++)
    {

        p_lrc = tmp[i]; // 获取数据
        // 判断歌词位置
        while (*p_lrc == '[')
            p_lrc += 10;
        // 处理时间
        p_time = tmp[i];
        while (*p_time == '[')
        {
            int m = 0, s = 0;
            sscanf(p_time, "[%d:%d", &m, &s);
            strcpy(lrc_data.lrc_buf, p_lrc);
            lrc_data.time = m * 60 + s;
            p_time += 10;
            head = insert_double_link(head, lrc_data);
        }
    }
    return head;
}
void link_free(LRC *head)
{
    if (NULL == head)
    {
        printf("head is null\n");
        return;
    }
    LRC *tmp = head;
    while (tmp != NULL)
    {
        tmp = tmp->next;
        free(head);
        head = tmp;
    }
}
void print_song_head(LRC *head, int head_len)
{
    LRC *tmp = head;
    clear_screen(); // 清屏
    cusor_hide();   // 隐藏光标
    for (int i = 0; i < head_len; i++)
    {
        set_fg_color(COLOR_RED); // 设置字体颜色
        cusor_moveto(40, i + 1); // 移动到
        printf("%s\n", tmp->lrc_buf);
        tmp = tmp->next;
    }
}
void color_pos_printf(char *str, int x, int y, int color)
{
    cusor_moveto(x, y);
    set_fg_color(color);
    printf("%s\n", str);
}
void time_printf(TIME tm, int head_len)
{
    char str[30];
    sprintf(str, "%02d:%02d", tm.minute, tm.second);
    color_pos_printf(str, 43, head_len + 1, COLOR_BLUE);
}
void lrc_printf(LRC *start_point, LRC *pb, int head_len)
{
    for (int i = 0; i < 5; i++)
    {
        if (start_point == pb) // 当前所唱歌词高亮
        {
            color_pos_printf(start_point->lrc_buf, 40, head_len + 2 + i, COLOR_MAGENTA);
        }
        else
        {
            color_pos_printf(start_point->lrc_buf, 40, head_len + 2 + i, COLOR_RED);
        }
        start_point = start_point->next;
    }
}
LRC *link_search(LRC *head, int m_time)
{
    LRC *pb = head;

    while (pb != NULL)
    {
        if (pb->time == m_time)
            return pb;
        else
            pb = pb->next;
    }
    return NULL;
}
LRC *find_start_point(LRC *head, LRC *pb)
{
    LRC *tmp = head;
    if (pb == head) // 第1个节点
        return head;
    else if (pb == head->next) // 第2个节点
        return head;

    // 判断 最后面几个节点，如果是，返回倒数第5个节点的地址
    else if (pb->next == NULL)
    {
        while (tmp->next->next->next->next != NULL)
        {
            if (tmp->next->next->next->next == pb)
            {
                return tmp;
            }
            tmp = tmp->next;
        }
        return NULL;
    }
    else if (pb->next->next == NULL)
    {
        while (tmp->next->next->next != NULL)
        {
            if (tmp->next->next->next == pb)
            {
                return tmp;
            }
            tmp = tmp->next;
        }
        return NULL;
    }

    else
    {
        while (tmp->next != NULL)
        {
            if (tmp->next->next == pb)
            {
                return tmp;
            }
            tmp = tmp->next;
        }
        return NULL;
    }
}

void m_clock(TIME *p_m_time)
{

    (*p_m_time).second++;
    if ((*p_m_time).second == 60)
    {
        (*p_m_time).second = 0;
        ++(*p_m_time).minute;
        if ((*p_m_time).minute == 60)
            (*p_m_time).minute = 0;
    }
}

void print_space(TIME m_time, int head_len)
{
    int n = m_time.minute * 60 + m_time.second;
    for (int i = 0; i < n; i++)
    {
        color_pos_printf("@", i + 10, head_len + 10, COLOR_RED);
    }
}